package com.zws.cucumber.var;

import javax.script.Bindings;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

public class ZwsVarBlockBindings implements Bindings {

    private ZwsVarBlock varBlock;

    public ZwsVarBlockBindings(ZwsVarBlock varBlock) {
        this.varBlock = varBlock;
    }

    @Override
    public Object put(String name, Object value) {
        return varBlock.put(name, value);
    }

    @Override
    public void putAll(Map<? extends String, ?> toMerge) {
        varBlock.putAll(toMerge);
    }

    @Override
    public void clear() {
        throw new UnsupportedOperationException();
    }

    @Override
    public Set<String> keySet() {
        Set<String> set = new LinkedHashSet<>(varBlock.getShallowVariables().keySet());
        ZwsVarBlock parent = varBlock.getParent();
        while (parent != null) {
            set.addAll(parent.getShallowVariables().keySet());
            parent = parent.getParent();
        }
        return set;
    }

    @Override
    public Collection<Object> values() {
        Set<Object> set = new LinkedHashSet<>(varBlock.getShallowVariables().values());
        ZwsVarBlock parent = varBlock.getParent();
        while (parent != null) {
            set.addAll(parent.getShallowVariables().values());
            parent = parent.getParent();
        }
        return set;
    }

    @Override
    public Set<Entry<String, Object>> entrySet() {
        Set<Entry<String, Object>> set = new LinkedHashSet<>(varBlock.getShallowVariables().entrySet());
        ZwsVarBlock parent = varBlock.getParent();
        while (parent != null) {
            set.addAll(parent.getShallowVariables().entrySet());
            parent = parent.getParent();
        }
        return set;
    }

    @Override
    public int size() {
        return varBlock.size();
    }

    @Override
    public boolean isEmpty() {
        return varBlock.isEmpty();
    }

    @Override
    public boolean containsKey(Object key) {
        return varBlock.containsKey((String) key);
    }

    @Override
    public boolean containsValue(Object value) {
        return varBlock.containsValue(value);
    }

    @Override
    public Object get(Object key) {
        return varBlock.get((String) key);
    }

    @Override
    public Object remove(Object key) {
        return varBlock.remove((String) key);
    }
}
